﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SIGCBI.Entities;
using System.Data;
using System.Data.Entity;
using System.Data.Objects;

namespace SIGCBI.Repository
{
    public interface IUsuarioRepository
    {
        List<USUARIO> GetAllFromUsuario();
        List<USUARIO> GetFromUsuarioByTrabajador(string descripcion);
        List<USUARIO> GetFromUsuarioByRol(string descripcion);
        USUARIO GetAllFromUsuarioByTrabajadorId(string dni);

        bool ExistDuplicidadUsuario(string idTrabajador, int ID);
        bool ExisteUsuario(string dni, string password);
        bool ExisteUsuarioRol(int IdTrabajador);
        bool PasswdCorrecta(string password);

        void AddUsuario(USUARIO usuario);
        void UpdateUsuario(USUARIO usuario);
        void DeleteUsuario(Int32 numero);

        void UpdatePasswdUsuario(USUARIO usuario);
    }

    public class UsuarioRepository : MasterDataAccess, IUsuarioRepository
    {

        public List<USUARIO> GetAllFromUsuario()
        {
            var query = from c in Context.USUARIOs.Include("TRABAJADOR").Include("ROL").Include("USUARIO_MENU.MENU")
                        select c;
            return query.ToList();
        }

        public List<USUARIO> GetFromUsuarioByTrabajador(string descripcion)
        {
            if (descripcion != "")
            {
                var query = from c in Context.USUARIOs.Include("TRABAJADOR").Include("ROL")
                            where c.TRABAJADOR.Nombres.ToUpper().Contains(descripcion.ToUpper()) ||
                                  c.TRABAJADOR.ApeMaterno.ToUpper().Contains(descripcion.ToUpper()) ||
                                  c.TRABAJADOR.ApePaterno.ToUpper().Contains(descripcion.ToUpper()) ||
                                  c.TRABAJADOR.Dni.ToUpper().Contains(descripcion.ToUpper())
                            select c;
                return query.ToList();
            }
            else
            {
                var query = from c in Context.USUARIOs.Include("TRABAJADOR").Include("ROL")
                            select c;
                return query.ToList();
            }
        }

        public List<USUARIO> GetFromUsuarioByRol(string descripcion)
        {
            if (descripcion != "")
            {
                var query = from c in Context.USUARIOs.Include("PERSONA").Include("ROL")
                            where c.ROL.Descripcion.ToUpper().Contains(descripcion.ToUpper())
                            select c;
                return query.ToList();
            }
            else
            {
                var query = from c in Context.USUARIOs.Include("TRABAJADOR").Include("ROL")
                            select c;
                return query.ToList();
            }
        }

        public USUARIO GetAllFromUsuarioByTrabajadorId(string dni)
        {
            var query = from c in Context.USUARIOs.Include("TRABAJADOR").Include("ROL").Include("USUARIO_MENU.MENU")
                        where c.TRABAJADOR.Dni == dni
                        select c;

            return query.SingleOrDefault();
        }

        public bool ExistDuplicidadUsuario(string idTrabajador, int ID)
        {
            var query = from c in Context.USUARIOs
                        where c.TRABAJADOR.Dni.ToUpper().CompareTo(idTrabajador.ToUpper()) == 0 && c.ID != ID
                        select c;
            return query.Any();
        }

        public bool ExisteUsuario(string dni, string password)
        {
            var query = from c in Context.USUARIOs
                        where c.TRABAJADOR.Dni.ToUpper().CompareTo(dni.ToUpper()) == 0 &&
                              c.Password.ToUpper().CompareTo(password.ToUpper()) == 0
                        select c;
            return query.Any();
        }

        public bool ExisteUsuarioRol(int IdTrabajador)
        {
            var query = from c in Context.USUARIOs
                        where c.IdTrabajador == IdTrabajador
                        select c;
            return query.Any();
        }

        public bool PasswdCorrecta(string password)
        {
            var query = from c in Context.USUARIOs
                        where c.Password.ToUpper().CompareTo(password.ToUpper()) == 0
                        select c;
            return query.Any();
        }

        public void AddUsuario(USUARIO usuario)
        {
            foreach (var item in usuario.USUARIO_MENU)
            {
                Context.Entry(item.MENU).State = EntityState.Unchanged;
                Context.Entry(item).State = EntityState.Added;
            }

            Context.Entry(usuario.TRABAJADOR).State = EntityState.Unchanged;

            Context.USUARIOs.Add(usuario);
            Context.SaveChanges();
        }

        public void UpdateUsuario(USUARIO usuario)
        {
            Context.Entry(usuario.TRABAJADOR).State = EntityState.Detached;
            Context.Entry(usuario.ROL).State = EntityState.Detached;

            foreach (var item in usuario.USUARIO_MENU)
            {
                item.MENU = null;
                item.USUARIO = null;

                Context.Entry(item).State = item.ID ==
                    Int32.Parse("0") ?
                    EntityState.Added : EntityState.Modified;

                item.IdMenu = item.IdMenu;
            }
            Context.Entry(usuario).State = EntityState.Modified;
            Context.SaveChanges();
        }

        public void DeleteUsuario(int numero)
        {
            var existe = Context.USUARIOs.Where(p => p.ID.Equals(numero)).SingleOrDefault();

            if (existe != null)
            {
                Context.USUARIOs.Remove(existe);
                Context.SaveChanges();
            }
        }

        public void UpdatePasswdUsuario(USUARIO usuario)
        {
            usuario.TRABAJADOR = null;
            usuario.USUARIO_MENU = null;

            Context.Entry(usuario).State = EntityState.Modified;
            Context.SaveChanges();
        }
    }
}
